package com.hz.monitoring.module.hardware.service.sensor_tenant_resource;

import com.hz.monitoring.framework.common.pojo.PageResult;
import com.hz.monitoring.module.hardware.controller.admin.sensor_tenant_resource.vo.*;
import com.hz.monitoring.module.hardware.convert.sensor_tenant_resource.SensorTenantResourceConvert;
import com.hz.monitoring.module.hardware.dal.dataobject.mcu_tenant_resource.McuTenantResourceDO;
import com.hz.monitoring.module.hardware.dal.dataobject.sensor_tenant_resource.SensorTenantResourceDO;
import com.hz.monitoring.module.hardware.dal.mysql.sensor_tenant_resource.SensorTenantResourceMapper;
import com.hz.monitoring.module.hardware.service.mcu_tenant_resource.McuTenantResourceService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.hz.monitoring.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.hz.monitoring.module.hardware.enums.ErrorCodeConstants.*;

/**
 * 传感器租户配置 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class SensorTenantResourceServiceImpl implements SensorTenantResourceService {

    @Resource
    private SensorTenantResourceMapper sensorTenantResourceMapper;

    @Resource
    private McuTenantResourceService mcuTenantResourceService;

    @Override
    public Long createSensorTenantResource(SensorTenantResourceCreateReqVO cmd) {
        // 插入
        SensorTenantResourceDO sensorTenantResource = SensorTenantResourceConvert.convert(cmd);
        McuTenantResourceDO mcuTenantResourceDO = mcuTenantResourceService.getMcuTenantResource(cmd.getMcuTenantResourceId());
        List<SensorTenantResourceDO> list = getSensorTenantResourceList(SensorTenantResourceListReqVO
                .builder()
                .mcuTenantResourceId(cmd.getMcuTenantResourceId())
                .build());

        Integer channelsNumber = cmd.getMcuChannel();

        if ((list.size() + 1) > mcuTenantResourceDO.getChannelsNumber() || channelsNumber < 0 || mcuTenantResourceDO.getChannelsNumber() < channelsNumber) {
            throw exception(SENSOR_TENANT_RESOURCE_CHANNEL_LIMIT);
        }
        Optional<SensorTenantResourceDO> optional = list.stream().filter(it -> it.getMcuChannel().equals(channelsNumber)).findFirst();
        if (optional.isPresent()) {
            throw exception(SENSOR_TENANT_RESOURCE_CHANNEL_EXISTS_ASSOCIATED);
        }
        sensorTenantResourceMapper.insert(sensorTenantResource);
        // 返回
        return sensorTenantResource.getId();
    }

    @Override
    public void updateSensorTenantResource(SensorTenantResourceUpdateReqVO cmd) {
        // 校验存在
        this.validateSensorTenantResourceExists(cmd.getId());
        // 更新
        SensorTenantResourceDO updateObj = SensorTenantResourceConvert.convert(cmd);

        McuTenantResourceDO mcuTenantResourceDO = mcuTenantResourceService.getMcuTenantResource(cmd.getMcuTenantResourceId());
        List<SensorTenantResourceDO> list = getSensorTenantResourceList(SensorTenantResourceListReqVO
                .builder()
                .mcuTenantResourceId(cmd.getMcuTenantResourceId())
                .build());

        list = list.stream().filter(it -> !(it.getId().equals(cmd.getId()))).collect(Collectors.toList());

        Integer channelsNumber = cmd.getMcuChannel();

        if ((list.size() + 1) > mcuTenantResourceDO.getChannelsNumber() || channelsNumber < 0 || mcuTenantResourceDO.getChannelsNumber() < channelsNumber) {
            throw exception(SENSOR_TENANT_RESOURCE_CHANNEL_LIMIT);
        }

        Optional<SensorTenantResourceDO> optional = list.stream().filter(it -> it.getMcuChannel().equals(channelsNumber)).findFirst();
        if (optional.isPresent()) {
            throw exception(SENSOR_TENANT_RESOURCE_CHANNEL_EXISTS_ASSOCIATED);
        }
        sensorTenantResourceMapper.updateById(updateObj);
    }

    @Override
    public void deleteSensorTenantResource(Long id) {
        // 校验存在
        this.validateSensorTenantResourceExists(id);
        // 删除
        sensorTenantResourceMapper.deleteById(id);
    }

    private void validateSensorTenantResourceExists(Long id) {
        if (sensorTenantResourceMapper.selectById(id) == null) {
            throw exception(SENSOR_TENANT_RESOURCE_NOT_EXISTS);
        }
    }

    @Override
    public SensorTenantResourceDO getSensorTenantResource(Long id) {
        return sensorTenantResourceMapper.selectById(id);
    }

    @Override
    public List<SensorTenantResourceDO> getSensorTenantResourceList(SensorTenantResourceListReqVO listReqVO) {
        return sensorTenantResourceMapper.selectList(listReqVO);
    }

    @Override
    public PageResult<SensorTenantResourceDO> getSensorTenantResourcePage(SensorTenantResourcePageReqVO pageReqVO) {
        return sensorTenantResourceMapper.selectPage(pageReqVO);
    }

    @Override
    public List<SensorTenantResourceDO> getSensorTenantResourceList(SensorTenantResourceExportReqVO exportReqVO) {
        return sensorTenantResourceMapper.selectList(exportReqVO);
    }

}
